#include <linux/mm.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/shrinker.h>
#include <linux/memcontrol.h>
#include <linux/compiler.h>

#include <memory/force_split_huge_page.h>

static bool force_split_huge_page = false;
static int __init set_force_split_huge_page(char *s)
{
	force_split_huge_page = true;
	return 1;
}

__setup("force_split_huge_page", set_force_split_huge_page);

void force_split_transparent_hugepage(struct page *tmp_page)
{
	if (unlikely(force_split_huge_page) && unlikely(tmp_page != NULL)) {
		struct shrink_control sc = {
			/* nid of pages of compound page is same */
			.nid = page_to_nid(tmp_page),
			/* force split 256 thps one time */
			.nr_to_scan = 256,
	#ifdef CONFIG_MEMCG
			/* memcg aware */
			.memcg = page_memcg(compound_head(tmp_page)),
	#endif
		};

		force_split_hugepage_deferred_split_scan(NULL, &sc);
	}
}

struct page* force_split_page_compound(struct page *page)
{
	if (unlikely(force_split_huge_page) &&
		unlikely(PageTransCompound(page)))
		return page;
	else
		return NULL;
}